#pragma once
#include <iostream>
#include <string>
#include <pthread.h>
#include <functional>
#include <unistd.h>

// V2
// namespace Threadnode
// {
	// template<typename T>
// 	enum class TSTART
// 	{
// 		NEW = 1,
// 		RUNING = 2,
// 		STOP = 3,
// 	};
// 	static int number = 1;
// 	template <typename T>
// 	class thread
// 	{
// 		using func_t = std::function<void(T&)>;
// 	private:
// 		static void *mission(void *agse)
// 		{
// 			thread<T> *as = static_cast<thread<T> *>(agse);
// 			as->_fun(as->_data);
// 			return nullptr;
// 		}

// 	public:
// 		thread(func_t fun, T& data) : _fun(fun), _data(data), _status(TSTART::NEW), _joinabl(true)
// 		{
// 			_name = "thread->" + std::to_string(number++);
// 			_pid = getpid();
// 		}
// 		bool start()
// 		{
// 			if (_status != TSTART::RUNING)
// 			{
// 				int n = pthread_create(&_tid, nullptr, mission, this);
// 				if (n != 0)
// 				{
// 					return false;
// 				}
// 				_status = TSTART::RUNING;
// 				return true;
// 			}
// 			return false;
// 		}
// 		bool stop()
// 		{
// 			if (_status == TSTART::RUNING)
// 			{
// 				int n = pthread_cancel(_tid);
// 				if (n != 0)
// 					return false;
// 				_status = TSTART::STOP;
// 				return true;
// 			}
// 			return false;
// 		}
// 		bool join()
// 		{
// 			// 如果线程没分离就要等待
// 			if (_joinabl)
// 			{
// 				int n = pthread_join(_tid, nullptr);
// 				if (n != 0)
// 					return false;
// 				_status = TSTART::STOP;
// 				return true;
// 			}
// 			return false;
// 		}
// 		void detach()
// 		{
// 			EnableDetach();
// 			pthread_detach(_tid);
// 		}
// 		void EnableDetach() { _joinabl = false; } // 更改为分离状态
// 		bool ISjoinabl() { return _joinabl; }
// 		TSTART status() { return _status; }
// 		pthread_t tid() { return _tid; }
// 		pid_t pid() { return _pid; }
// 		std::string name() { return _name; }
// 		T& data() {return _data;}
// 		~thread()
// 		{
// 		}

// 	private:
// 		std::string _name; // 线程名字
// 		pthread_t _tid;	   // 线程id
// 		pid_t _pid;		   // 线程所属进程id
// 		bool _joinabl;	   // 线程是否分离，默认是不分离
// 		func_t _fun;
// 		TSTART _status;
// 		T _data;
// 	};
// }

//------------------------------------------------------------------------------------
// V1
namespace ThreadModule
{
    using func_t = std::function<void(std::string name)>;
    static int number = 1;
    enum class TSTATUS
    {
        NEW,
        RUNNING,
        STOP
    };

    class Thread
    {
    private:
        // 成员方法！
        static void *Routine(void *args)
        {
            Thread *t = static_cast<Thread *>(args);
            t->_status = TSTATUS::RUNNING;
            t->_func(t->Name());
            return nullptr;
        }
        void EnableDetach() { _joinable = false; }

    public:
        Thread(func_t func) : _func(func), _status(TSTATUS::NEW), _joinable(true)
        {
            _name = "Thread-" + std::to_string(number++);
            _pid = getpid();
        }
        bool Start()
        {
            if (_status != TSTATUS::RUNNING)
            {
                int n = ::pthread_create(&_tid, nullptr, Routine, this); // TODO
                if (n != 0)
                    return false;
                return true;
            }
            return false;
        }
        bool Stop()
        {
            if (_status == TSTATUS::RUNNING)
            {
                int n = ::pthread_cancel(_tid);
                if (n != 0)
                    return false;
                _status = TSTATUS::STOP;
                return true;
            }
            return false;
        }
        bool Join()
        {
            if (_joinable)
            {
                int n = ::pthread_join(_tid, nullptr);
                if (n != 0)
                    return false;
                _status = TSTATUS::STOP;
                return true;
            }
            return false;
        }
        void Detach()
        {
            EnableDetach();
            pthread_detach(_tid);
        }
        bool IsJoinable() { return _joinable; }
        std::string Name() {return _name;}
        ~Thread()
        {
        }

    private:
        std::string _name;
        pthread_t _tid;
        pid_t _pid;
        bool _joinable; // 是否是分离的，默认不是
        func_t _func;
        TSTATUS _status;
    };
}